<template>
  <div class="dialog">
    <el-dialog
      v-model="dialogVisible"
      title="创建"
      width="30%"
      @close="handleClose">
      <el-form :model="form" label-width="120px" ref="appFormRef" :rules="rules">
        <el-form-item label="名称" prop="name">
          <el-input v-model="form.name" />
        </el-form-item>
        <el-form-item label="年龄" prop="age">
          <el-input v-model="form.age" />
        </el-form-item>
        <el-form-item label="性别" prop="sex">
          <el-select v-model="form.sex" placeholder="请选择性别">
            <el-option label="男" value="man" />
            <el-option label="女" value="woman" />
          </el-select>
        </el-form-item>

      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitAction">确认</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, reactive, toRefs } from 'vue'
import { createApp, editApp } from '@/api/index'
// 引入表单ref类型，和rules类型，2.0.2没有这些ts类型，参看游戏加速器项目，没有写类型，也不报错
// import type { FormInstance, FormRules } from 'element-plus'
// import type { FormInstance, FormRules } from 'element-plus'
// expose 用来控制组件向外暴漏的内容，如果不设置，父组件能访问子组件的所有属性和方法，暴漏之后就只能访问暴漏的了
export default defineComponent({
  // 尽管事件声明是可选的，我们还是推荐你完整地声明所有要触发的事件，以此在代码中作为文档记录组件的用法。同时，事件声明能让 Vue 更好地将事件和透传 attribute 作出区分，从而避免一些由第三方代码触发的自定义 DOM 事件所导致的边界情况。
  // emits:['refresh'],
  setup(props, context) {

    const appFormRef = ref();
    const state = reactive({
      dialogVisible: false,
      type: 'create',
      id: 0,
      form: {
        name: '',
        age: '',
        sex: ''
      },
      rules: {
        name: [
          { required: true, message: '请输入名称', trigger: 'blur' },
        ],
        age: [
          { required: true, message: '请输入年龄', trigger: 'blur' },
        ],
        sex: [
          { required: true, message: '请选择性别', trigger: 'change' },
        ],
      }
    })
    onMounted(() => {
      console.log('onMounted')
    })
    const handleClose = () => {
      console.log('before-close')
      appFormRef.value.resetFields()
    }
    const commitHandle = (type: string, row: any) => {
      if (type == 'create') {
        state.type = 'create';
        state.form = {
          name: '',
          age: '',
          sex: ''
        }
      } else if (type == 'edit') {
        const data = JSON.parse(JSON.stringify(row))
        state.type = 'edit';
        state.id = data.id;
        state.form = data
      }
      state.dialogVisible = true;
      console.log('触发成功expose')
    }

    const submitAction = () => {
      //  const fn = `${state.type}Action`;
      if (state.type == 'create') {
        console.log(state.type, 'type')
        createAction()
      } else {
        editAction()
      }
    }
    const createAction = () => {
      appFormRef.value.validate((valid: boolean) => {
        if (valid) {
          createApp(state.form).then(res => {
            console.log(res, '成功')
            state.dialogVisible = false;
            context.emit('refresh')
          }).catch(err => {
            console.log(err)
          })
        }
      })
    }
    const editAction = () => {
      appFormRef.value.validate((valid: boolean) => {
        if (valid) {
          editApp(state.id, state.form).then(res => {
            console.log(res, '成功')
            state.dialogVisible = false;
            context.emit('refresh')
          }).catch(err => {
            console.log(err)
          })
        }
      })

    }
    // context.expose({ commitHandle }) // context下有expose属性，参考文档可以这样写
    // 但是 只是父组件触发子组件中的方法，通过expose暴露不是很必要


    return {
      ...toRefs(state),
      handleClose,
      commitHandle,
      submitAction,
      appFormRef
    }
  }
})
</script>

